/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controle.gui.frames.internos;

import controle.gui.frames.ControleFramePrincipal;
import controle.gui.frames.internos.superclasses.Controle;
import controle.gui.utils.ApagaElementosDaInterface;
import controle.gui.utils.EnabledGUIElements;
import controle.gui.utils.TamanhoJTextField;
import controle.gui.utils.setEnabledGUIElements;
import controle.interfaces.Constantes;
import gui.frames.internos.IFLogradouros;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import modelo.Logradouro;
import modelo.Municipio;
import persistencia.dao.AbstractDAO;
import persistencia.dao.TransacaoDAO;

/**
 *
 * @author Maycon Fernando Silva Brito
 * @author mayconfsbrito@gmail.com
 */
public class ControleLogradouros extends Controle {

     //Variáveis da classe
    private IFLogradouros frame = null;

    /*
     * Construtor da classe
     */
    public ControleLogradouros(IFLogradouros frame) {
        super(frame);
        this.frame = frame;
    }

    /**
     * Inicializa o frame
     */
    public void inicializa() {

        //Torna o frame visível
        frame.setVisible(true);

        //Limita o tamanho do JTextField
        TamanhoJTextField.limitaTamanho(new int[]{100, 100}, frame.textNome, frame.textBuscaNome);

        this.limparGUI();

        //Inicializa eventos da tabela
        frame.tabela.getSelectionModel().addListSelectionListener(frame.listener);
        frame.tabela.getColumnModel().getSelectionModel().addListSelectionListener(frame.listener);

    }

    /**
     * Especificações em @InternalFrame
     */
    public void guiAtiva(boolean estado) {
        if (estado) {
            setEnabledGUIElements.enabledJComponent(frame.buttonCadastro);
            setEnabledGUIElements.disabledJComponent(frame.buttonAlterar);

        } else {
            setEnabledGUIElements.enabledJComponent(frame.buttonAlterar);
            setEnabledGUIElements.disabledJComponent(frame.buttonCadastro);
        }
    }

    /**
     * Verifica o acesso do usuário para utilizar o frame
     */
    protected void verificaAcessos() {

        /*
         * Verifica a permissao de @user para este frame
         */
        if (!ControleFramePrincipal.acessos.get(Constantes.PERMISSAO_CADASTRA_ALTERA_LOCAIS).isAcesso()) {
            EnabledGUIElements.disabledJComponent(frame.buttonCadastro, frame.buttonAlterar);
        }
    }

    /**
     * Limpa os componentes do frame
     */
    public void limparGUI() {

        frame.tabela.clearSelection();
        new ApagaElementosDaInterface().apagaJTextField(frame.textId, frame.textNome, frame.textNomeMunicipio, frame.textCodigoMunicipio);

        //Configura o comportamento da gui de acordo com as permissões do usuário
        this.guiAtiva(true);
        this.verificaAcessos();
    }

    /**
     * Preenche todos os componentes da GUI a partir do objeto selecionado na tabela
     */
    public void tabelaPreencheGUI() {

        int linha = frame.tabela.getSelectedRow();
        Integer cod;
        try {
            cod = (Integer) frame.tabela.getValueAt(linha, 0);
        } catch (IndexOutOfBoundsException er) {
            cod = 0;
            return;
        }

        List<Logradouro> consulta = AbstractDAO.consultar("from Logradouro l LEFT JOIN FETCH l.municipio m WHERE l.idLogradouro=" + cod);

        if (consulta.size() > 0) {
            Logradouro log = consulta.get(0);
            frame.textId.setText(Integer.toString(log.getIdLogradouro()));
            frame.textNome.setText(log.getNome());
            frame.textNomeMunicipio.setText(log.getMunicipio().getNome());
            frame.textCodigoMunicipio.setText(log.getMunicipio().getCodigo());

            //Configura o comportamento dos botões da interface
            frame.buttonCadastro.setEnabled(false);
            EnabledGUIElements.enabledJComponent(frame.buttonAlterar);
            this.guiAtiva(false);
            this.verificaAcessos();

        }
    }

    /**
     * Especificações do método em @InternalFrame
     */
    protected void listarTodosElementosNaTabela() {

        List<Logradouro> list = AbstractDAO.listar("Logradouro");
        listarPesquisaNaTabela(list);

        if (list != null) {
            listarPesquisaNaTabela(list);
        }
    }

    /**
     * Especificações do método em @InternalFrame
     */
    private void listarPesquisaNaTabela(List<Logradouro> list) {

        frame.tabela.getColumnModel().getColumn(0).setMinWidth(30);
        frame.tabela.getColumnModel().getColumn(1).setMinWidth(300);
        frame.tabela.getColumnModel().getColumn(2).setMinWidth(50);
        frame.tabela.getColumnModel().getColumn(3).setMinWidth(200);

        DefaultTableModel modelo = (DefaultTableModel) frame.tabela.getModel();
        modelo.setNumRows(0);
        limparGUI();

        try {

            if (list != null) {
                for (int i = 0; i < list.size(); i++) {
                    Logradouro log = list.get(i);
                    modelo.addRow(new Object[]{log.getIdLogradouro(), log.getNome(), log.getMunicipio().getCodigo(), log.getMunicipio().getNome()});
                }
            }
        } catch (Exception er) {
            JOptionPane.showMessageDialog(frame, "Erro ao listar os objetos na tabela!\n\n" + er, "Erro na listagem!", JOptionPane.ERROR_MESSAGE);
            er.printStackTrace();
        }

        //Permite o evento de ordernar a tabela a partir do click do mouse
        frame.tabela.setAutoCreateRowSorter(true);
    }

    /**
     * Instancia o logradouro a partir dos elementos da interface gráfica
     *
     * @return
     */
    public Logradouro criaLogradouro(int opcao) {

        //Caso o usuário confirme o evento
        if (opcao == JOptionPane.YES_OPTION) {

            //Verifica se o nome da logradouro está preenchido
            if (!frame.textNome.getText().trim().isEmpty()) {

                //Verifica se o município foi selecionado
                if (!frame.textCodigoMunicipio.getText().trim().isEmpty()) {

                    //Instancia as variáveis
                    String nome = frame.textNome.getText();

                    //Verifica se o município existe
                    List<Municipio> listMun = AbstractDAO.consultar("Municipio", "codigo='" + frame.textCodigoMunicipio.getText().trim() + "'");
                    if (listMun.isEmpty()) {
                        JOptionPane.showMessageDialog(frame, "Código de município inexistente.", "Código de município inválido!", JOptionPane.WARNING_MESSAGE);
                        return null;
                    }

                    Municipio mun = listMun.get(0);
                    Logradouro log = new Logradouro(mun, nome);

                    //Verifica o id do logradouro
                    if (!frame.textId.getText().trim().isEmpty()) {
                        log.setIdLogradouro(Integer.parseInt(frame.textId.getText().trim()));
                    }
                    
                    //Retorna o objeto
                    return log;

                } else {
                    JOptionPane.showMessageDialog(frame, "Atenção! O logradouro deve ser selecionado.", "Logradouro não selecionado!", JOptionPane.WARNING_MESSAGE);
                }

            } else {
                JOptionPane.showMessageDialog(frame, "Atenção! O nome da logradouro deve ser preenchido.", "Nome não preenchido!", JOptionPane.WARNING_MESSAGE);

            }
        }
        return null;

    }

    /**
     * Cadastra uma localidade através do frame
     */
    public void cadastrar() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja cadastrar " + frame.textNome.getText()
                + "?", "Cadastro de logradouro", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Logradouro log = this.criaLogradouro(opcao);

        //Realiza o cadastro
        if (log != null) {
            if (AbstractDAO.cadastrar(log)) {
                JOptionPane.showMessageDialog(frame, "Logradouro cadastrado com sucesso!", "Cadastro.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
                
                int id = AbstractDAO.max(Logradouro.class, "idLogradouro");
                TransacaoDAO.cadastrar("Cadastrou o logradouro id=" + id + ".");
            }
        }

    }

    /**
     * Altera um logradouro através do frame
     */
    public void alterar() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja alterar a logradouro " + frame.textNome.getText()
                + "?", "Alteração de logradouro", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Logradouro log = this.criaLogradouro(opcao);

        //Realiza o cadastro
        if (log != null) {
            if (AbstractDAO.alterar(log)) {
                JOptionPane.showMessageDialog(frame, "Logradouro Alterado com sucesso!", "Alteração.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
                
                TransacaoDAO.cadastrar("Alterou o lograduro id=" + log.getIdLogradouro() + ".");
            }
        }

    }

    /**
     * Exclui uma localidade através do frame
     */
    public void excluir() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja excluir o logradouro " + frame.textNome.getText()
                + "?", "Exclusão de logradouro", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Logradouro log = this.criaLogradouro(opcao);

        //Realiza o cadastro
        if (log != null) {
            if (AbstractDAO.excluir(log)) {
                JOptionPane.showMessageDialog(frame, "Logradouro excluído com sucesso!", "Exclusão.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
            }
        }

    }

    /**
     * Realiza a busca de um determinado objeto a partir dos parâmetros definidos no @frame
     */
    public void buscar() {

        //Captura os parametros do frame
        String nome = frame.textBuscaNome.getText();
        String codigoMunicipio = frame.textBuscaCodigoMunicipio.getText();

        //Realiza a busca no bd
        //Captura o id do município caso ele tenha sido selecionado
        List<Logradouro> list = null;

        //Incrementa a string para consutar a busca
        String query = "";
        if (codigoMunicipio != null && !codigoMunicipio.isEmpty()) {

            //Verifica se o código do município existe
            List<Municipio> listMun = AbstractDAO.consultar("Municipio", "codigo='" + codigoMunicipio + "'");
            if (listMun.size() > 0) {
                Municipio mun = listMun.get(0);
                query += "m.idMunicipio=" + mun.getIdMunicipio();
                frame.textBuscaNomeMunicipio.setText(mun.getNome());

            } else {
                JOptionPane.showMessageDialog(frame, "Não existe nenhum município com este código.", "Código de município existente!",
                        JOptionPane.WARNING_MESSAGE);
                return;
            }

        }
        if (nome != null && !nome.trim().equals("")) {
            if (query.length() > 1) {
                query += " AND ";
            }
            query += " l.nome like '%" + nome + "%' ";
        }

        if (!query.equals("")) {
            list = AbstractDAO.consultar("from Logradouro l left join fetch l.municipio m where " + query);
        }

        
        //Lista os objetos encontrados na tabela
        if (list != null) {
            this.listarPesquisaNaTabela(list);
        } else {
            this.listarPesquisaNaTabela(null);
        }
    }

    /**
     * Limpa apenas os componentes de busca e lista a tabela de objetos com todos os objetos do bd
     */
    public void limparBusca() {

        new ApagaElementosDaInterface().apagaJTextField(frame.textBuscaNome, frame.textBuscaCodigoMunicipio, frame.textBuscaNomeMunicipio);
        this.listarPesquisaNaTabela(null);

    }

    /**
     * Evento de textCodigoMunicipio
     *
     * @return
     */
    public boolean textCodigoMunicipio(JTextField textCodigoMunicipio, JTextField textNomeMunicipio) {

        String codigoMun = textCodigoMunicipio.getText().trim();

        //Verifica se o município existe
        List<Municipio> list = AbstractDAO.consultar("Municipio", "codigo='" + codigoMun + "'");
        if (list.size() > 0) {
            textNomeMunicipio.setText(list.get(0).getNome());

        } else {
            new ApagaElementosDaInterface().apagaJTextField(textNomeMunicipio);
            JOptionPane.showMessageDialog(frame, "Não existe nenhum município com este código.", "Código de município inexistente!",
                    JOptionPane.WARNING_MESSAGE);
            return false;
        }

        return true;
    }

}
